﻿using FAP.Cores.CaptchaCenter;
using FAP.Cores.Threading;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FAP.DataAccess;

namespace FAP.Cores.Threading
{
    public class FapWork : FapTask
    {
        private int currentStep = 0;
        private chitietnghiepvu ctnv;
        private taikhoan tk = new taikhoan();
        public Requesting.Requester requester = new Requesting.Requester();
        private CaptchaDTO m_capcha;
        public System.Net.WebResponse response;
        private FapWork() { }

        public string LastHTML = "";

        public FapWork(chitietnghiepvu ct)
        {
            this.ctnv = ct;
            if (ct == null)
                throw new Exception("FapWork(chitietnghiepvu ct) not implement");
        }

        public override object RunIt()
        {
            var lstBuocThucHien = ctnv.buocthuchiens.OrderBy(m => m.thutu).ToList();
            for (int i = currentStep; i < lstBuocThucHien.Count; i++)
            {
                buocthuchien step = lstBuocThucHien[i];
                string link = step.link;
                string data = "";
                if (step.method.ToLower() == "get")
                {
                    var response = requester.GetData(link, false, tk.cookie);
                    if (response == null)
                    {
                        throw new Exception("Can not getting data from " + link);
                    }
                    else
                    {
                        LastHTML = requester.GetHtmlFromResponse(response);
                    }
                }
                else
                {
                    if (m_capcha == null)
                    {
                        var capchaStepDetail = step.chitietbuocthuchiens.Where(m => m.fieldformat.ten.ToLower() == "capchavalue").SingleOrDefault();
                        CaptchaDTO capcha = new CaptchaDTO();
                        if (capchaStepDetail != null)
                        {
                            capcha.html = LastHTML;
                            capcha.xpath = capchaStepDetail.dulieumacdinh;
                            _strCapchaValueFieldName = capchaStepDetail.tenfield;
                            CaptchaTask capchaTask = new CaptchaTask(capcha);
                            capchaTask.onFinished += onFinishedCapcha;
                            capchaTask.onError += onErrorCapcha;
                            FAP.Cores.Threading.ThreadControl.AddTasks(capchaTask);
                            currentStep=i;
                            this.WaitCaptcha();
                            return null;
                        }
                    }
                    foreach (var stepDetail in step.chitietbuocthuchiens)
                    {
                        switch (stepDetail.fieldformat.ten.ToLower())
                        {
                            case "username":
                                string strUserName = this.tk.tendangnhap;
                                if (string.IsNullOrEmpty( strUserName))
                                {
                                    throw new Exception("Missing taikhoan, use LoginBy(taikhoan tk)");
                                }
                                data += string.Format("&{0}={1}", stepDetail.tenfield, strUserName);
                                break;
                            case "password":
                                string strPassword = this.tk.matkhau;
                                if (string.IsNullOrEmpty(strPassword))
                                {
                                    throw new Exception("Missing taikhoan, use LoginBy(taikhoan tk)");
                                }
                                data += string.Format("&{0}={1}", stepDetail.tenfield, strPassword);
                                break;
                            case "email":
                                this._strEmailFieldName = stepDetail.tenfield;
                                string strEmail = this.GetEmail();
                                if (strEmail == null)
                                {
                                    throw new Exception("Missing Email field");
                                }
                                data += string.Format("&{0}={1}", stepDetail.tenfield, strEmail);
                                break;
                            case "notsend":
                                data += string.Format("&{0}={1}", stepDetail.tenfield, "");
                                break;
                            case "default":
                                data += string.Format("&{0}={1}", stepDetail.tenfield, stepDetail.dulieumacdinh);
                                break;
                            case "humanverify":
                                this._strHumanverifyFieldName = stepDetail.tenfield;
                                string strHumanverify = this.GetHumanverify();
                                if (strHumanverify == null)
                                {
                                    throw new Exception("Missing Humanverify field");
                                }
                                data += string.Format("&{0}={1}", stepDetail.tenfield, strHumanverify);
                                break;
                            case "token":
                                this._strTokenFieldName = stepDetail.tenfield;
                                string strToken = this.GetToken();
                                if (strToken == null)
                                {
                                    throw new Exception("Missing Token field");
                                }
                                data += string.Format("&{0}={1}", stepDetail.tenfield, strToken);
                                break;
                            case "title":
                                this._strTitleFieldName = stepDetail.tenfield;
                                string strTitle = this.GetTitle();
                                if (strTitle == null)
                                {
                                    throw new Exception("Missing Title field");
                                }
                                data += string.Format("&{0}={1}", stepDetail.tenfield, strTitle);
                                break;
                            case "content":
                                this._strContentFieldName = stepDetail.tenfield;
                                string strContent = this.GetContent();
                                if (strContent == null)
                                {
                                    throw new Exception("Missing Content field");
                                }
                                data += string.Format("&{0}={1}", stepDetail.tenfield, strContent);
                                break;
                            case "bb_userid":
                                this._strBBUseridFieldName = stepDetail.tenfield;
                                string strBBUserid = this.GetBBUserid();
                                if (strBBUserid == null)
                                {
                                    throw new Exception("Missing bb_userid field");
                                }
                                data += string.Format("&{0}={1}", stepDetail.tenfield, strBBUserid);
                                break;
                            case "capchavalue":

                                this._strCapchaValueFieldName = stepDetail.tenfield;
                                data += string.Format("&{0}={1}", stepDetail.tenfield, m_capcha.captcha);
                                break;
                        }
                    }

                    if (data != "" && link != "")
                    {
                        data = data.Replace("\0", "");
                        response = requester.PostData(link, data);
                        LastHTML = requester.GetHtmlFromResponse(response);
                    }
                }
            }
            return base.RunIt();
        }
        #region BB_Userid
        private string _strBBUseridFieldName;
        public string BBUseridFieldName
        {
            get { return _strBBUseridFieldName; }
        }
        public virtual string GetBBUserid()
        {
            return null;
        }
        #endregion

        public void onFinishedCapcha(object sender, object result)
        {
            if (result == null)
                return;
            CaptchaDTO c = (CaptchaDTO)result;
            this.m_capcha = c;
            //this.RunIt();
            FAP.Cores.Threading.ThreadControl.AddTasks(this);

        }

        public static void onErrorCapcha(object sender, object result)
        {
            //m_log.Error(result);
            throw new Exception("Capcha not avilable");
        }

        #region Capcha
        private string _strCapchaValueFieldName;

        public string CapchaValue
        {
            get { return _strCapchaValueFieldName; }
        }
        private string GetCapchaValue()
        {
            return null;
        }
        #endregion

        #region Content
        private string _strContentFieldName;

        public string ContentFieldName
        {
            get { return _strContentFieldName; }
        }
        public virtual string GetContent()
        {
            return null;
        }
        #endregion

        #region Title
        private string _strTitleFieldName;

        public string TitleFieldName
        {
            get { return _strTitleFieldName; }
        }
        public virtual string GetTitle()
        {
            return null;
        }
        #endregion

        #region Token
        private string _strTokenFieldName;

        public string TokenFieldName
        {
            get { return _strTokenFieldName; }
        }
        public virtual string GetToken()
        {
            return null;
        }
        #endregion

        #region Humanverify
        private string _strHumanverifyFieldName;

        public string HumanverifyFieldName
        {
            get { return _strHumanverifyFieldName; }
        }
        public virtual string GetHumanverify()
        {
            return null;
        }
        #endregion

        #region Email
        private string _strEmailFieldName;

        public string EmailFieldName
        {
            get { return _strEmailFieldName; }
        }
        public virtual string GetEmail()
        {
            return null;
        }
        #endregion

        public void LoginBy(taikhoan tk)
        {
            this.tk = tk;
        }


    }
}
